package com.kitty.game.item.service;

import com.kitty.game.pet.model.Pet;
import com.kitty.game.role.model.Role;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.model.RoleEquipField;
import com.kitty.game.config.GemSet;
import com.kitty.game.config.PetStoneSet;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.bag.message.RespIconCartoon;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.enter.RespGeneralNotify;
import com.kitty.game.enter.RespNotifyMisc;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.equip.model.EquipField;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.item.ItemDataPool;
import com.kitty.game.onlinemall.service.MallService;
import com.kitty.game.pet.model.PetStone;
import com.kitty.game.pet.service.PetService;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.utils.NotifyModules;
import com.kitty.mina.message.MessagePusher;
import com.kitty.game.attribute.AttrService;
import com.kitty.game.base.service.BagService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.lang.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
//后加
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 宠物妖石
 */
@Service
public class PetStoneService {
    private static final Logger logger = LoggerFactory.getLogger(PetStoneService.class);
    @Resource
    MallService mallService;
    @Resource
    AttrService attrService;
    @Resource
    EquipService equipService;
    @Resource
    PetService petService;
    private static final List<Short> STONE_POS = Arrays.asList((short) 3074, (short) 3330, (short) 3586);

    /**
     * 初始化宠物妖石配置
     */
    public void init() {
        List<PetStoneSet> stoneSets = SpringUtils.getBean(Dao.class).query(PetStoneSet.class, Cnd.NEW());
        Map<Short, Map<String, PetStoneSet>> levelAndName2Stone = new HashMap<>();
        Map<Short, PetStoneSet> index2Stone = new HashMap<>(stoneSets.size());
        for (PetStoneSet stone : stoneSets) {
            index2Stone.put(stone.getSetIndex(), stone);
            Map<String, PetStoneSet> name2Stone = levelAndName2Stone.computeIfAbsent(stone.getLevel(), k -> new HashMap<>());
            name2Stone.put(stone.getName(), stone);
        }
        ItemDataPool.levelAndName2Stone = levelAndName2Stone;
        ItemDataPool.index2Stone = index2Stone;
        /**宝石的配置*/
        //List<GemSet> gemSets = SpringUtils.getBean(Dao.class).query(GemSet.class, Cnd.NEW());
        List<GemSet> gemSets = new ArrayList<>();
        {
            GemSet gemSet = new GemSet();
            gemSet.setIndex_((short)301);
            gemSet.setName("芙蓉石");
            gemSet.setNeedName("蓝松石");
            gemSets.add(gemSet);
        }
        {
            GemSet gemSet = new GemSet();
            gemSet.setIndex_((short)302);
            gemSet.setName("红宝石");
            gemSet.setNeedName("芙蓉石");
            gemSets.add(gemSet);
        }
        {
            GemSet gemSet = new GemSet();
            gemSet.setIndex_((short)303);
            gemSet.setName("蓝宝石");
            gemSet.setNeedName("红宝石");
            gemSets.add(gemSet);
        }
        Map<Short, GemSet> index2Gem = new HashMap<>();
        gemSets.forEach(gemSet -> index2Gem.put(gemSet.getIndex_(), gemSet));
        ItemDataPool.index2Gem = index2Gem;
    }

    /**
     * 设置妖石基础属性
     */
    public void setBasicAttr(PetStoneSet petStoneSet, RoleEquip roleEquip, boolean isLimit, int num) {
        /**基础属性*/
        {
            LinkedHashMap<Short, FiedValue> basic = new LinkedHashMap<>();
            List<FiedValue> values = new ArrayList<>();
            values.add(new FiedValue(89, ""));
            values.add(new FiedValue(205, 0));
            values.add(new FiedValue(261, 0));
            values.add(new FiedValue(206, 132));//使用类型
            values.add(new FiedValue(74, 6));//物品类型
            values.add(new FiedValue(34, 0));
            values.add(new FiedValue(31, petStoneSet.getLevel()));
            values.add(new FiedValue(118, petStoneSet.getNimbus()));//灵气
            values.add(new FiedValue(40, petStoneSet.getIcon()));
            values.add(new FiedValue(215, 0));
            values.add(new FiedValue(348, 0));
            values.add(new FiedValue(207, 500));//出手价格
            values.add(new FiedValue(264, ""));
            values.add(new FiedValue(248, 0));
            values.add(new FiedValue(1, petStoneSet.getName()));
            values.add(new FiedValue(306, String.valueOf(roleEquip.getId())));
            values.add(new FiedValue(38, 0));
            values.add(new FiedValue(209, "金色"));
            values.add(new FiedValue(84, roleEquip.getId()));
            values.add(new FiedValue(270, isLimit ? 2 : 0));
            values.add(new FiedValue(203, num));//数量
            values.add(new FiedValue(41, 8));//类型
            values.add(new FiedValue(3001, ""));//别名
            values.add(new FiedValue(887, 0));
            values.add(new FiedValue(282, 1));//叠加类型
            values.forEach(fieldValue -> basic.put(fieldValue.getType(), fieldValue));
            RoleEquipField roleEquipField = new RoleEquipField();
            roleEquipField.setType((short) 1);
            roleEquipField.setField(basic);
            roleEquip.getFields().put(roleEquipField.getType(), roleEquipField);
        }
        /**蓝色属性*/
        {
            LinkedHashMap<Short, FiedValue> extra = new LinkedHashMap<>();
            extra.put(petStoneSet.getFieldId(), new FiedValue(petStoneSet.getFieldId(), petStoneSet.getValue()));
            RoleEquipField roleEquipField = new RoleEquipField();
            roleEquipField.setType((short) 514);
            roleEquipField.setField(extra);
            roleEquip.getFields().put(roleEquipField.getType(), roleEquipField);
        }
    }


    /**
     * 获得妖石
     */
    public void getPetStone(Role role, String petStoneName, int pos, boolean isLimit, int level, int num) {
        getPetStone(role, getStoneSetBy(petStoneName, (short) level), pos, isLimit, num);
    }


    private void getPetStone(Role role, PetStoneSet petStoneSet, int pos, boolean isLimit, int addNum) {
        for (RoleEquip oldEquip : role.getEquipBox().getEquips().values()) {
            if (oldEquip == null || oldEquip.getPosition() > 165 || oldEquip.getPosition() < 41 ||
                    Strings.isEmpty(oldEquip.getType()) || !oldEquip.getType().equals("妖石")) {
                continue;
            }
            if (oldEquip.getName().equals(petStoneSet.getName())) {
                if (oldEquip.isLimit() != isLimit) continue;
                if (oldEquip.queryLevel() != petStoneSet.getLevel()) continue;
                short num = oldEquip.queryNum();
                if (num + addNum < 999) {
                    oldEquip.alterNum(num + addNum);
                    equipService.refreshRoleEquip(role, oldEquip);
                    role.save();
                    RespIconCartoon respIconCartoon = new RespIconCartoon();
                    respIconCartoon.setName(oldEquip.getName());
                    respIconCartoon.setParam(oldEquip.getId() + "");
                    MessagePusher.pushMessage(role, respIconCartoon);
                    MessagePusher.pushMessage(role, new RespNotifyMiscEx("你获得了#R" + addNum + "#n块#R" + oldEquip.getName() + "#n。"));
                    return;
                }
            }
        }
        RoleEquip roleEquip = new RoleEquip();
        roleEquip.setType("妖石");
        int id = mallService.getRoleEquipId();
        roleEquip.setId(id);
        roleEquip.setName(petStoneSet.getName());
        roleEquip.setRoleId(role.getRoleId());
        roleEquip.setPosition(pos);
        setBasicAttr(petStoneSet, roleEquip, isLimit, addNum);
        equipService.add(role, roleEquip);
        equipService.refreshRoleEquip(role, roleEquip);

        RespIconCartoon respIconCartoon = new RespIconCartoon();
        respIconCartoon.setName(roleEquip.getName());
        respIconCartoon.setParam(roleEquip.getId() + "");
        MessagePusher.pushMessage(role, respIconCartoon);

        MessagePusher.pushMessage(role, new RespNotifyMiscEx("你获得了#R" + addNum + "#n块#R" + roleEquip.getName() + "#n。"));
    }

    public PetStoneSet getStoneSetBy(String stoneName, short level) {
        return ItemDataPool.levelAndName2Stone.get(level).get(stoneName);
    }

    /**
     * 移除妖石
     */
    public void removeStone(Role role, byte petPos, String toRemoveStone) {
        Pet pet = petService.getPetByPos(petPos, role);
        for (PetStone stone : pet.getStones()) {
            if (stone.getName().equals(toRemoveStone)) {
                List<FiedValue> extraFields = new ArrayList<>();
                extraFields.add(new FiedValue(stone.getFieldId(), 0));
                addPetExtraFields(pet, extraFields);
                pet.getStones().remove(stone);
                break;
            }
        }
        petService.refreshPetInfo(role, pet);
        MessagePusher.pushMessage(role, new RespMsg("#Y" + pet.getName() + "#n成功去除了妖石#R" + toRemoveStone + "#n。"));
    }

    /**
     * 取宠物妖石增益
     */
    public List<EquipField> getStoneExtraFields(Pet pet) {
        Set<PetStone> stones = pet.getStones();
        /**大于等于1才说明有妖石*/
        if (stones.size() >= 1) {
            List<EquipField> fieldList = new ArrayList<>();
            int i = 0;
            List<FiedValue> extraFields = new ArrayList<>();
            for (PetStone stone : stones) {
                ArrayList<FiedValue> values = new ArrayList<>();
                EquipField field = new EquipField();
                extraFields.add(new FiedValue(stone.getFieldId(), stone.getValue()));
                values.add(new FiedValue(31, stone.getLevel()));
                values.add(new FiedValue(1, stone.getName()));
                values.add(new FiedValue(stone.getFieldId(), stone.getValue()));
                values.add(new FiedValue(118, stone.getNimbus()));
                field.setType(STONE_POS.get(i));
                field.setFieldValues(values);
                fieldList.add(field);
                i++;
            }
            addPetExtraFields(pet, extraFields);
            return fieldList;
        }
        return null;
    }

    /**
     * 给宠物添加上增益属性
     */
    private void addPetExtraFields(Pet pet, List<FiedValue> values) {
        values.forEach(value -> {
            if (value.getType() == 7) {//气血
                pet.setExtraLife(attrService.getValue(value.getValue()));
            } else if (value.getType() == 8) {//防御
                pet.setExtraDefense(attrService.getValue(value.getValue()));
            } else if (value.getType() == 10) {//法伤
                pet.setExtraMagPower(attrService.getValue(value.getValue()));
            } else if (value.getType() == 3) {//物伤
                pet.setExtraPhyPower(attrService.getValue(value.getValue()));
            } else if (value.getType() == 12) {//法力
                pet.setExtraMana(attrService.getValue(value.getValue()));
            } else if (value.getType() == 14) {//速度
                pet.setExtraSpeed(attrService.getValue(value.getValue()));
            }
        });
    }

    /**
     * 合成妖石用到index
     */
    private PetStoneSet getStoneSetBy(short index) {
        return ItemDataPool.index2Stone.get(index);
    }


    /**
     * 合成妖石
     */
    public void upgradeStone(Role role, int index, byte type) {
        short pos = SpringUtils.getBean(BagService.class).getPos(role, false);
        if (pos <= 0) {
            return;
        }
        PetStoneSet stoneSet = getStoneSetBy((short) index);
        if (stoneSet == null) {
            logger.error("没有找到index[{}]妖石配置 合成宝石", index);

            GemSet gemSet = ItemDataPool.index2Gem.get((short) index);
            if (gemSet != null) {
                upgradeGem(role, gemSet, pos, type);
            }
            return;
        }


        RoleEquip limitStone = getNeedStone(role, stoneSet.getName(), (short) (stoneSet.getLevel() - 1), true);
        RoleEquip noLimitStone = getNeedStone(role, stoneSet.getName(), (short) (stoneSet.getLevel() - 1), false);
        int limitStoneNum = limitStone != null ? limitStone.queryNum() : 0;
        int noLimitStoneNum = noLimitStone != null ? noLimitStone.queryNum() : 0;


        /**type 1是不使用限制单次合成 2是使用限制 单次合成
         * 3是不使用限制一键合成 4是使用限制一键合成*/
        int num = 0;
        if (type == 1) {
            if (noLimitStoneNum < 3) {
                return;
            }
            num = 1;
            equipService.delEquipNum(role, noLimitStone, 3);
            getPetStone(role, stoneSet, pos, false, num);
        } else if (type == 2) {
            if (limitStoneNum < 3) {
                if (noLimitStoneNum < 3) {
                    return;
                }
                num = 1;
                equipService.delEquipNum(role, noLimitStone, 3);
                getPetStone(role, stoneSet, pos, false, num);
            } else {
                num = 1;
                equipService.delEquipNum(role, limitStone, 3);
                getPetStone(role, stoneSet, pos, true, num);
            }
        } else if (type == 3) {
            if (noLimitStoneNum < 3) {
                return;
            }
            num = noLimitStoneNum / 3;
            getPetStone(role, stoneSet, pos, false, num);
            equipService.delEquipNum(role, noLimitStone, num * 3);
        } else if (type == 4) {
            if (limitStoneNum < 3) {
                if (noLimitStoneNum < 3) {
                    return;
                }
                num = noLimitStoneNum / 3;
                getPetStone(role, stoneSet, pos, false, num);
                equipService.delEquipNum(role, noLimitStone, num * 3);
            } else {
                num = limitStoneNum / 3;
                getPetStone(role, stoneSet, pos, true, num);
                equipService.delEquipNum(role, limitStone, num * 3);
            }
        }

        RespGeneralNotify notify = new RespGeneralNotify();
        notify.setNotify(NotifyModules.NOTIFY_FINISH_ALCHEMY);
        notify.setValue(String.valueOf(1));
        MessagePusher.pushMessage(role, notify);

        MessagePusher.pushMessage(role, new RespNotifyMisc("你消耗了#R" + num * 3 + "#n块#R" + (stoneSet.getLevel() - 1) + "级" + stoneSet.getName() + "#n炼制了#R" + num + "#n块#R" + stoneSet.getLevel() + "级" + stoneSet.getName() + "#n。"));
        MessagePusher.pushMessage(role, new RespMsg("炼制成功！你获得了#R" + num + "#n块#R" + stoneSet.getLevel() + "级" + stoneSet.getName() + "#n。"));

    }

    /**
     * 合成宝石
     */
    private void upgradeGem(Role role, GemSet gemSet, short pos, byte type) {
        boolean isLimit = type == 2 || type == 4;
        int gemNum = equipService.getCount(gemSet.getNeedName(), isLimit, role);
        int num = 0,limitNum=0;
        if (type == 1 || type == 2) {
            if (gemNum < 3) {
                return;
            }
            num = 1;
            limitNum = equipService.delRoloEquip(gemSet.getNeedName(), 3, isLimit, role);
        } else if (type == 3 || type == 4) {
            if (gemNum < 3) {
                return;
            }
            num = gemNum / 3;
            limitNum = equipService.delRoloEquip(gemSet.getNeedName(), 3 * num, isLimit, role);
        }

        if (num <= 0) {
            return;
        }
        RoleEquip newEquip = equipService.identityGem(role, gemSet.getName(), pos, num);
        if(limitNum>=1){
            newEquip.addLimitTime(limitNum);
        }

        MessagePusher.pushMessage(role, new RespIconCartoon(newEquip.getName()));

        equipService.refreshRoleEquip(role, newEquip);

        MessagePusher.pushMessage(role, new RespNotifyMisc("你消耗了#R" + num * 3 + "#n块#R" + gemSet.getNeedName() + "#n炼制了#R" + num + "#n块#R" + gemSet.getName() + "#n。"));
        MessagePusher.pushMessage(role, new RespMsg("炼制成功！你获得了#R" + num + "#n块#R"+ gemSet.getName() + "#n。"));

        RespGeneralNotify notify = new RespGeneralNotify();
        notify.setNotify(NotifyModules.NOTIFY_FINISH_ALCHEMY);
        notify.setValue(String.valueOf(1));
        MessagePusher.pushMessage(role, notify);

    }

    private RoleEquip getNeedStone(Role role, String stoneName, short level, boolean isLimit) {
        Set<RoleEquip> equips = new HashSet<>(role.getEquipBox().getEquips().values());
        return equips.stream().filter(roleEquip -> roleEquip.getPosition() > 40 && roleEquip.getPosition() < 166).
                filter(roleEquip -> roleEquip.getName().equals(stoneName)).
                filter(roleEquip -> roleEquip.isLimit() == isLimit).
                filter(roleEquip -> roleEquip.queryLevel() == level).findFirst().orElse(null);
    }
}
